<!DOCTYPE html>
<html>
<head>
    

    

    



    <meta charset="utf-8">
    
    
    
    
    <title>计算机网络——TCP的三次握手与四次挥手 | 博客主页 | 世界是个球，前方总有路！</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    
    <meta name="theme-color" content="#3F51B5">
    
    
    <meta name="keywords" content="计算机网络">
    <meta name="description" content="一、前言&amp;emsp;&amp;emsp;今天刚看完《计算机网络——自顶向下方法》这本书的运输层这一章。直到今天我才知道，TCP协议居然有这么复杂（之前上课都没怎么认真听），这一章节总共七十多页，主要介绍UDP与TCP，但UDP的内容却只占不超过5页，大部分的篇幅都是在讲解TCP的机制。但是就算这样，我还是感觉这本书对TCP的讲解不够详细，忽略了很多内容和细节，导致我无法将这本书对TCP的讲解串通在一起，感">
<meta property="og:type" content="article">
<meta property="og:title" content="计算机网络——TCP的三次握手与四次挥手">
<meta property="og:url" content="http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/index.html">
<meta property="og:site_name" content="博客主页">
<meta property="og:description" content="一、前言&amp;emsp;&amp;emsp;今天刚看完《计算机网络——自顶向下方法》这本书的运输层这一章。直到今天我才知道，TCP协议居然有这么复杂（之前上课都没怎么认真听），这一章节总共七十多页，主要介绍UDP与TCP，但UDP的内容却只占不超过5页，大部分的篇幅都是在讲解TCP的机制。但是就算这样，我还是感觉这本书对TCP的讲解不够详细，忽略了很多内容和细节，导致我无法将这本书对TCP的讲解串通在一起，感">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/1.png">
<meta property="og:image" content="http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/2.png">
<meta property="og:image" content="http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/3.png">
<meta property="article:published_time" content="2020-03-06T15:54:56.000Z">
<meta property="article:modified_time" content="2020-03-18T12:08:46.334Z">
<meta property="article:author" content="特务依昂">
<meta property="article:tag" content="计算机网络">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/1.png">
    
        <link rel="alternate" type="application/atom+xml" title="博客主页" href="/blog/atom.xml">
    
    <link rel="shortcut icon" href="/blog/img/title.png">
    <link rel="stylesheet" href="//unpkg.com/hexo-theme-material-indigo@latest/css/style.css">
    <script>window.lazyScripts=[]</script>

    <!-- custom head -->
    

<meta name="generator" content="Hexo 4.2.0"></head>

<body>
    <div id="loading" class="active"></div>

    <aside id="menu" class="hide" >
  <div class="inner flex-row-vertical">
    <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menu-off">
        <i class="icon icon-lg icon-close"></i>
    </a>
    <div class="brand-wrap" style="background-image:url(/blog/img/brand.jpg)">
      <div class="brand">
        <a href="/blog/" class="avatar waves-effect waves-circle waves-light">
          <img src="/blog/img/avatar.jpg">
        </a>
        <hgroup class="introduce">
          <h5 class="nickname">特务依昂</h5>
          <a href="mailto:1131564805@qq.com" title="1131564805@qq.com" class="mail">1131564805@qq.com</a>
        </hgroup>
      </div>
    </div>
    <div class="scroll-wrap flex-col">
      <ul class="nav">
        
            <li class="waves-block waves-effect">
              <a href="/blog/"  >
                <i class="icon icon-lg icon-home"></i>
                主页
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/blog/archives"  >
                <i class="icon icon-lg icon-archives"></i>
                博客
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/blog/tags"  >
                <i class="icon icon-lg icon-tags"></i>
                标签
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/blog/categories"  >
                <i class="icon icon-lg icon-th-list"></i>
                分类
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://github.com/tewuyiang" target="_blank" >
                <i class="icon icon-lg icon-github"></i>
                Github
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://weibo.com/u/5516635708/" target="_blank" >
                <i class="icon icon-lg icon-weibo"></i>
                Weibo
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://www.cnblogs.com/tuyang1129/" target="_blank" >
                <i class="icon icon-lg icon-link"></i>
                博客园
              </a>
            </li>
        
      </ul>
    </div>
  </div>
</aside>

    <main id="main">
        <header class="top-header" id="header">
    <div class="flex-row">
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light on" id="menu-toggle">
          <i class="icon icon-lg icon-navicon"></i>
        </a>
        <div class="flex-col header-title ellipsis">计算机网络——TCP的三次握手与四次挥手</div>
        
        <div class="search-wrap" id="search-wrap">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
                <i class="icon icon-lg icon-chevron-left"></i>
            </a>
            <input type="text" id="key" class="search-input" autocomplete="off" placeholder="输入感兴趣的关键字">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="search">
                <i class="icon icon-lg icon-search"></i>
            </a>
        </div>
        
        
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menuShare">
            <i class="icon icon-lg icon-share-alt"></i>
        </a>
        
    </div>
</header>
<header class="content-header post-header">

    <div class="container fade-scale">
        <h1 class="title">计算机网络——TCP的三次握手与四次挥手</h1>
        <h5 class="subtitle">
            
                <time datetime="2020-03-06T15:54:56.000Z" itemprop="datePublished" class="page-time">
  2020-03-06
</time>


	<ul class="article-category-list"><li class="article-category-list-item"><a class="article-category-list-link" href="/blog/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>

            
        </h5>
    </div>

    


</header>


<div class="container body-wrap">
    
    <aside class="post-widget">
        <nav class="post-toc-wrap post-toc-shrink" id="post-toc">
            <h4>TOC</h4>
            <ol class="post-toc"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#一、前言"><span class="post-toc-number">1.</span> <span class="post-toc-text">一、前言</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#二、解析"><span class="post-toc-number">2.</span> <span class="post-toc-text">二、解析</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-1-TCP的报文格式"><span class="post-toc-number">2.1.</span> <span class="post-toc-text">&amp;emsp;2.1 TCP的报文格式</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-2-TCP三次握手的过程"><span class="post-toc-number">2.2.</span> <span class="post-toc-text">&amp;emsp;2.2 TCP三次握手的过程</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-3-为什么是三次握手而不是两次"><span class="post-toc-number">2.3.</span> <span class="post-toc-text">&amp;emsp;2.3 为什么是三次握手而不是两次</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-4-TCP四次挥手的过程"><span class="post-toc-number">2.4.</span> <span class="post-toc-text">&amp;emsp;2.4 TCP四次挥手的过程</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-5-客户端为什么要等待一段时间再释放资源"><span class="post-toc-number">2.5.</span> <span class="post-toc-text">&amp;emsp;2.5 客户端为什么要等待一段时间再释放资源</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#emsp-2-6-断开连接为什么需要四次挥手"><span class="post-toc-number">2.6.</span> <span class="post-toc-text">&amp;emsp;2.6 断开连接为什么需要四次挥手</span></a></li></ol></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#三、总结"><span class="post-toc-number">3.</span> <span class="post-toc-text">三、总结</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#四、参考"><span class="post-toc-number">4.</span> <span class="post-toc-text">四、参考</span></a></li></ol>
        </nav>
    </aside>


<article id="post-计算机网络——TCP的三次握手与四次挥手"
  class="post-article article-type-post fade" itemprop="blogPost">

    <div class="post-card">
        <h1 class="post-card-title">计算机网络——TCP的三次握手与四次挥手</h1>
        <div class="post-meta">
            <time class="post-time" title="2020-03-06 23:54:56" datetime="2020-03-06T15:54:56.000Z"  itemprop="datePublished">2020-03-06</time>

            
	<ul class="article-category-list"><li class="article-category-list-item"><a class="article-category-list-link" href="/blog/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>



            
<span id="busuanzi_container_page_pv" title="文章总阅读量" style='display:none'>
    <i class="icon icon-eye icon-pr"></i><span id="busuanzi_value_page_pv"></span>
</span>


        </div>
        <div class="post-content" id="post-content" itemprop="postContent">
            <h2 id="一、前言"><a href="#一、前言" class="headerlink" title="一、前言"></a>一、前言</h2><p>&emsp;&emsp;今天刚看完《计算机网络——自顶向下方法》这本书的运输层这一章。直到今天我才知道，<code>TCP</code>协议居然有这么复杂（之前上课都没怎么认真听），这一章节总共七十多页，主要介绍<code>UDP</code>与<code>TCP</code>，但<code>UDP</code>的内容却只占不超过<code>5</code>页，大部分的篇幅都是在讲解<code>TCP</code>的机制。但是就算这样，我还是感觉这本书对<code>TCP</code>的讲解不够详细，忽略了很多内容和细节，导致我无法将这本书对<code>TCP</code>的讲解串通在一起，感觉前后矛盾，同时也有很多地方无法理解。这一章读下来，我对<code>TCP</code>有了更深入的了解，但是同时也对它有了更多的疑问。由此看来，想要真正弄懂<code>TCP</code>，不能仅仅依靠这种入门书籍，应该选择一些专门讲解这一块内容的书籍进行研究。</p>
<p>&emsp;&emsp;接下来我准备将这几天看的<code>TCP</code>的内容进行一次总结，以博客的形式将这些内容记录下来，算是加深印象吧。这篇博客就先来说一说<code>TCP</code>的<strong>三次握手</strong>和<strong>四次挥手</strong>，也就是<code>TCP</code>连接的建立与断开，算是<code>TCP</code>中相对比较简单的部分。</p>
<br>

<h2 id="二、解析"><a href="#二、解析" class="headerlink" title="二、解析"></a>二、解析</h2><h3 id="emsp-2-1-TCP的报文格式"><a href="#emsp-2-1-TCP的报文格式" class="headerlink" title="&emsp;2.1 TCP的报文格式"></a>&emsp;2.1 TCP的报文格式</h3><p>&emsp;&emsp;想要了解<code>TCP</code>的三次握手与四次挥手，首先得了解一下<code>TCP</code>的报文格式，因为这两个过程需要依赖<code>TCP</code>报文中的一些字段。下面我们通过一幅图来讲解<code>TC</code>P的报文格式：</p>
<figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="1.png" alt="" title="">
                </div>
                <div class="image-caption"></div>
            </figure>

<p>&emsp;&emsp;我只介绍<code>TCP</code>报文中，与三次握手和四次挥手有关的部分：</p>
<ul>
<li><strong>源端口号</strong>：本次<code>TCP</code>连接中，发起连接的主机使用的端口号；</li>
<li><strong>目的端口号</strong>：本次<code>TCP</code>连接主，接受连接的主机使用的端口号；</li>
<li><strong>序号</strong>：通过TCP传输的每一个数据段，都有一个序号，作用是为了确认此数据段的顺序。网络中允许传输的数据长度是有限制的，所以当我们要通过<code>TCP</code>传输一个较大的数据时，<code>TCP</code>会将数据切割成很多小的数据段进行传输。而将这些小的数据段发送到目的主机时（发送方会同时发送多个数据），并不能保证它们是按顺序到达目的地，所以对于每一个数据段，都要有一个序号，来标识它们是属于总数据的哪一部分，以保证在目的主机中能将他们重新拼接。</li>
<li><strong>确认序号</strong>：接收方若接收到一个数据段，会发送一个确认报文给发送方，告诉发送方已经接收到这个数据段，而确认序号的作用就是告诉发送方接收到了哪条数据段。若接收方接收到了序号为<code>n</code>的报文段，则确认序号将是<code>n+1</code>，表示它已经接收了<code>n</code>，下一条想要接收<code>n+1</code>；</li>
<li><strong>首部长度</strong>：<code>TCP</code>报文的首部+数据的字节数；</li>
<li><strong>ACK</strong>：只有<code>1 bit</code>的标志位，若为<code>1</code>，表示这个数据段中的确认序号是有效的，即这个数据报是对之前接收到的某个报文的确认（一个<code>TCP</code>报文可以同时作为确认报文和传递数据报文）。</li>
<li><strong>RST</strong>：只有<code>1 bit</code>的标志位，若客户端向服务器的一个端口请求建立<code>TCP</code>连接，但是服务器的那个端口并不允许建立连接（比如没开启此端口），则服务器会回送一个<code>TCP</code>报文，将<code>RST</code>位置为1，告诉客户端不要再向这个端口发起连接；</li>
<li><strong>SYN</strong>：只有<code>1 bit</code>的标志位，若为<code>1</code>，表示这是一条建立连接的<code>TCP</code>报文段；</li>
<li><strong>FIN</strong>：只有<code>1 bit</code>的标志位，若为<code>1</code>，表示这是一条断开连接的<code>TCP</code>报文段；</li>
</ul>
<p>&emsp;&emsp;对于<code>TCP</code>报文格式，就先介绍这么多，其余的部分虽然也很重要，但是并没有作用于<code>TCP</code>连接的建立与断开，所以就不在这里叙述了。</p>
<br>

<h3 id="emsp-2-2-TCP三次握手的过程"><a href="#emsp-2-2-TCP三次握手的过程" class="headerlink" title="&emsp;2.2 TCP三次握手的过程"></a>&emsp;2.2 TCP三次握手的过程</h3><p>&emsp;&emsp;<code>TCP</code>建立连接的过程中需要发送三次报文，所以<code>TCP</code>建立连接也被称为<strong>三次握手</strong>，接下来我就来讲讲这三次握手的过程，假设客户端向服务器发起<code>TCP</code>连接：</p>
<ul>
<li><p><strong>第一步</strong>：客户端的<code>TCP</code>程序首先向服务器的<code>TCP</code>程序发送一个<code>TCP</code>报文。这个报文不包含数据，且它的<code>SYN</code>标志位被置为<code>1</code>，表示这是一条建立连接的<code>TCP</code>报文段，因此这个报文段也被称为<strong>SYN报文段</strong>。客户端的<code>TCP</code>程序随机选择一个序号作为客户端报文的初始序号（假设序号为<code>client_isn</code>），放入这个报文段的序号部分。这个报文段由运输层传递到网络层后，被封装在一个<code>IP</code>数据报中发往服务器；</p>
</li>
<li><p><strong>第二步</strong>：包含<code>SYN</code>报文段的<code>IP</code>数据报被服务器接收，服务器的网络层将<code>SYN</code>数据报抽取出来，交给运输层，同时服务器为该<code>TCP</code>连接分配资源（包括发送缓存、接收缓存和变量等），并向客户发送允许连接的<code>TCP</code>报文段。这条允许连接的报文段不包含数据，<code>SYN</code>标志位也被置为<code>1</code>，同时它的<code>ACK</code>标志位也被置为1，表示它是<code>SYN</code>报文段的确认报文，所以这条允许连接的报文段也被称为<strong>SYNACK报文段</strong>。服务器随机选择一个序号，作为服务器报文段的初始序号（假设称为<code>server_isn</code>），并将其放入<code>SYNACK</code>报文段的序号部分，同时确认号字段被设置为<code>client_isn + 1</code>（<code>SYN</code>报文段的序号+1）。这个报文段可以解释为服务器向客户端说：“我收到了你的连接请求，我允许你连接，我的初始序号是<code>server_isn</code>”。</p>
</li>
<li><p><strong>第三步</strong>：当客户端接收到<code>SYNACK</code>报文段后，它也将为<code>TCP</code>连接分配资源（缓存和变量），同时生成一条<code>SYNACK</code>报文段的确认报文，并发送给服务器。由于经过上面两个步骤，已经算是建立了连接，所以这次的<code>SYN</code>标志位将被置为<code>0</code>，而不是<code>1</code>（<code>ACK</code>标志位是<code>1</code>）。同时，这条报文段的序号被设置为<code>client_isn + 1</code>（第一条客户报文的序号是<code>client_isn</code>，而这是它的下一条，所以<code>+1</code>），而确认序号被设置为<code>server_isn + 1</code>（第一条服务器报文的序号是<code>server_isn</code>，客户端成功接收，所以期望服务器下一次发送<code>server_isn + 1</code>）。和上面两条报文不同，第三条报文可以携带数据，比如<code>HTTP</code>的请求就是在<code>TCP</code>的第三次握手报文中发送到服务器的。</p>
</li>
</ul>
<p>&emsp;&emsp;经过上面这三个步骤，<code>TCP</code>连接就算正式建立完毕，客户端和服务器可以相互发送数据了。下面是这个过程的图片形式：</p>
<figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="2.png" alt="" title="">
                </div>
                <div class="image-caption"></div>
            </figure>

<br>

<h3 id="emsp-2-3-为什么是三次握手而不是两次"><a href="#emsp-2-3-为什么是三次握手而不是两次" class="headerlink" title="&emsp;2.3 为什么是三次握手而不是两次"></a>&emsp;2.3 为什么是三次握手而不是两次</h3><p>&emsp;&emsp;首先我们要明确，两次握手是必要的。第一次握手，客户端将<code>SYN</code>报文发送到服务器，服务器接收到报文后，即可确认客户端到服务器是可达的；而服务器向客户端发送响应的<code>SYNACK</code>报文，客户端接收到后，即可确认服务器到客户端也是可达的。至此，连接已经算是建立，那为什么还要有第三次握手呢？</p>
<p>&emsp;&emsp;客户端和服务器的握手过程，不仅仅是确认互相可达的过程，更重要的是一个<strong>同步</strong>的过程，<code>SYN</code>就是同步（Synchronize）的缩写。对于<code>TCP</code>报文段来说，<strong>序号</strong>是一个至关重要的部分，它保证了<code>TCP</code>传输数据的完整性。而我们上面也说过，<code>TCP</code>报文的初始序号不是从<code>0</code>开始的，而是一个随机的序号，<strong>而所谓的同步，就是<code>TCP</code>客户端和服务器互相同步初始序号的过程</strong>。第一次握手，客户端发送<code>SYN</code>报文，将自己的初始序号发送到了服务器，服务器接收到后，向客户端发送<code>SYNACK</code>报文段，告诉客户端已经收到了它的初始序号，同时在这个报文段中带上了自己的初始序号。这个时候，第三次握手的作用就出来了：<strong>第三次握手实际上就是客户端在告诉服务器，自己已经收到了它的初始序号，完成了同步，可以开始相互传输数据了</strong>。若没有第三次握手，服务器将无法保证客户端接收到了自己的<code>SYNACK</code>报文段，若此时<code>SYNACK</code>报文段丢失，客户端不知道服务器的初始序号，将无法处理之后到达客户端的数据。</p>
<p>&emsp;&emsp;在很多书籍和网上的博客中还流传另外一种说法。若仅仅是两次握手，将产生以下问题：客户端向服务器发送<code>SYN</code>报文段请求建立连接，但是没有在指定时间内收到<code>SYNACK</code>报文段，所以客户端认为<code>SYN</code>报文段在网络中丢失，则再次发送<code>SYN</code>报文段，并成功接收到了<code>SYNACK</code>报文段，但是客户端在很短的时间内就断开了<code>TCP</code>连接。然而，最初的<code>SYN</code>报文并没有丢失，只是传输时延太长，过了许久才到达。等它到达服务器时，其实客户端已经与服务器建立过<code>TCP</code>连接，并且已经断开了。此时服务器接收到这条<code>SYN</code>报文段，以为客户端又想建立一条新的连接，于是向客户端回送<code>ACK</code>报文，并为连接分配了资源。由于没有第三次握手，服务器将不知道这其实是上一次连接的报文，于是将它创建一个新的<code>TCP</code>连接并维持，直至因为太久没有接收到数据而释放。这种情况非常浪费资源，所以为了防止这种情况的发生，才需要客户端的再一次确认。</p>
<p>&emsp;&emsp;实际上，上面所述的第一点才是<code>TCP</code>三次握手的原因，第二个只能算是顺带的好处吧，从建立连接的报文被称为<code>SYN</code>（同步）就可以看出这点。</p>
<br>

<h3 id="emsp-2-4-TCP四次挥手的过程"><a href="#emsp-2-4-TCP四次挥手的过程" class="headerlink" title="&emsp;2.4 TCP四次挥手的过程"></a>&emsp;2.4 TCP四次挥手的过程</h3><p>&emsp;&emsp;说完了三次握手，下面来说说四次挥手的过程。<code>TCP</code>在断开连接时，客户端与服务器之间要交换四次报文，所以，<code>TCP</code>的断开连接也叫四次挥手。</p>
<ul>
<li><strong>第一步</strong>：客户端进程发出断开连接指令，这将导致客户端的<code>TCP</code>程序创建一个特殊的<code>TCP</code>报文段，发送到服务器。这个报文段的<code>FIN</code>字段被置为1，表示这是一条断开连接的报文；</li>
<li><strong>第二步</strong>：服务器接收到客户端发来的断开连接报文，向客户端回送这个报文的确认报文（<code>ACK</code>字段为<code>1</code>），告诉服务器已经接收到<code>FIN</code>报文，并允许断开连接；</li>
<li><strong>第三步</strong>：服务器发送完确认报文后，服务器的<code>TCP</code>程序创建一条自己的断开连接报文，此报文的<code>FIN</code>字段被置为<code>1</code>，然后发往客户端；</li>
<li><strong>第四步</strong>：客户端接收到服务器发来的<code>FIN</code>报文段，则产生一条确认报文（<code>ACK</code>为<code>1</code>），发送给服务器，告知服务器已经接收到了它的断开报文。服务器接收到这条<code>ACK</code>报文段后，释放<code>TCP</code>连接相关的资源（缓存和变量），而<strong>客户端等待一段时间后</strong>（半分钟、一分钟或两分钟），也释放处于客户端的缓存和变量；</li>
</ul>
<p>&emsp;&emsp;以上就是四次挥手的过程，相对建立连接来说要简单一些。以上是以客户端请求断开连接来举例，但其实也可以由服务器断开连接。</p>
<figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="3.png" alt="" title="">
                </div>
                <div class="image-caption"></div>
            </figure>

<br>

<h3 id="emsp-2-5-客户端为什么要等待一段时间再释放资源"><a href="#emsp-2-5-客户端为什么要等待一段时间再释放资源" class="headerlink" title="&emsp;2.5 客户端为什么要等待一段时间再释放资源"></a>&emsp;2.5 客户端为什么要等待一段时间再释放资源</h3><p>&emsp;&emsp;看完上面四次挥手的过程，可能有的人会有疑问，四次挥手之后，连接不是已经断开了吗，为什么客户端还要等待一段时间再释放资源呢？原因有两个：</p>
<ul>
<li><strong>原因一</strong>：客户端接收到服务器发送的<code>FIN</code>报文后（第三次挥手），会回送一条确认报文（第四次挥手），但是，客户端并不知道这条确认报文是否可以顺利到达服务器。若这条确认报文在传送到服务器的过程中损坏、丢失或超时，将引起服务器重新发送<code>FIN</code>报文，客户端接收到后，将需要再次发送一条确认报文，直到服务器正确接收。但是，客户端发送确认报文后，立刻释放资源，将导致无法处理重传的<code>FIN</code>报文，所以客户端需要等待一段时间，直到确认没有出现上述情况出现再释放资源。</li>
<li><strong>原因二</strong>：<code>TCP</code>四次挥手完成后，理论上已经断开了连接，但是这不代表之前通过这条连接发送的所有数据都处理完毕了，有些可能还在网络中传输。若在四次挥手后，立即释放客户端的资源，然后客户端立即以同一个源端口，向服务器的同一个目的端口再次建立一个<code>TCP</code>连接，这个连接和上一个的 源端口+源<code>IP</code>+目的端口+目的<code>IP</code> 都一模一样，此时将会产生问题。若上一次连接遗留在网络中的报文此时到达，将会被当做新连接传输的数据处理，于是可能会产生一些不可预估的错误。所以，客户端在断开连接后，需要等待一段时间，直到网络中遗留的数据都死掉，才释放资源，而在资源没有被释放前，是不允许建立一个 源端口+源<code>IP</code>+目的端口+目的<code>IP</code> 都一模一样的<code>TCP</code>连接的（因为<code>TCP</code>套接字由这四部分标识）。</li>
</ul>
<br>

<h3 id="emsp-2-6-断开连接为什么需要四次挥手"><a href="#emsp-2-6-断开连接为什么需要四次挥手" class="headerlink" title="&emsp;2.6 断开连接为什么需要四次挥手"></a>&emsp;2.6 断开连接为什么需要四次挥手</h3><p>&emsp;&emsp;有的人可能也会想，断开连接为什么是四次挥手，不能是两次呢？其中一方请求断开连接，另一方确认即可，为什么这个过程需要两边各发起一次？原因就是：<strong>TCP连接是全双工的</strong>。什么是全双工，即<code>A</code>与<code>B</code>建立连接，则<code>A</code>可以向<code>B</code>发送数据，而<code>B</code>也可以向<code>A</code>发送数据。</p>
<p>&emsp;&emsp;我们知道断开连接的请求什么时候发起？当然就是在不再有数据需要发送时。我们依旧以客户端向服务器断开连接为例。假设客户端和服务器建立了一个<code>TCP</code>连接，在客户端需要向服务器发送的数据都发送完后，客户端就可以向服务器发送一个<code>FIN</code>报文段，请求断开连接；服务器接收到后，将会回送一个<code>ACK</code>报文，告诉客户端，自己已经收到了它断开连接的请求。若只有两次挥手，这个时候连接就算是断开了。但是这样真的合理吗？答案当然是否定的。</p>
<p>&emsp;&emsp;客户端发送完数据后，告诉服务器，我没有数据了，可以和你断开，但是不代表服务器没有数据需要发送到客户端了呀。<code>TCP</code>是一个全双工的连接，代表服务器也有可能有数据需要发送到客户端。所以，只有当两端的数据都发送完毕，连接才能安全的断开。因此，服务器接收到了客户端的<code>FIN</code>报文段，他会等到自己所有的数据发送完，然后也向客户端发送一个<code>FIN</code>报文，告诉客户端我也没数据了，这时候连接才能真正断开，两端各自释放资源。</p>
<br>

<h2 id="三、总结"><a href="#三、总结" class="headerlink" title="三、总结"></a>三、总结</h2><p>&emsp;&emsp;以上对<code>TCP</code>的三次握手和四次挥手做了一个比较全面的讲解，相信看完之后可以让人对<code>TCP</code>连接的建立和断开有更深入的理解。但是，这一部分内容实际上只是<code>TCP</code>中比较简单的一块，尽管如此，还是用了这么多篇幅去讲解，可想而知<code>TCP</code>的复杂性。我后面还将写几篇关于TCP其他方面的内容，希望在搜集资料和编写的过程中，能够加深我对它的理解。</p>
<br>

<h2 id="四、参考"><a href="#四、参考" class="headerlink" title="四、参考"></a>四、参考</h2><ol>
<li>《计算机网络——自顶向下方法（原书第七版）》</li>
<li>多篇博客</li>
</ol>

        </div>

        <blockquote class="post-copyright">
    
    <div class="content">
        
<span class="post-time">
    最后更新时间：<time datetime="2020-03-18T12:08:46.334Z" itemprop="dateUpdated">2020-03-18 20:08:46</time>
</span><br>


        
        世界是个球，前方总有路！
        
    </div>
    
    <footer>
        <a href="http://tewuyiang.gitee.io/blog">
            <img src="/blog/img/avatar.jpg" alt="特务依昂">
            特务依昂
        </a>
    </footer>
</blockquote>

        


        <div class="post-footer">
            
	<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/blog/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/" rel="tag">计算机网络</a></li></ul>


            
<div class="page-share-wrap">
    

<div class="page-share" id="pageShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&title=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&pic=http://tewuyiang.gitee.io/blog/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&title=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&source=一个未来程序员的博客~~~" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&via=http://tewuyiang.gitee.io/blog" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>



    <a href="javascript:;" id="shareFab" class="page-share-fab waves-effect waves-circle">
        <i class="icon icon-share-alt icon-lg"></i>
    </a>
</div>



        </div>
    </div>

    
<nav class="post-nav flex-row flex-justify-between">
  
    <div class="waves-block waves-effect prev">
      <a href="/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6/" id="post-prev" class="post-nav-link">
        <div class="tips"><i class="icon icon-angle-left icon-lg icon-pr"></i> Prev</div>
        <h4 class="title">计算机网络——TCP的拥塞控制</h4>
      </a>
    </div>
  

  
    <div class="waves-block waves-effect next">
      <a href="/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8%E4%B8%8E%E5%A4%9A%E8%B7%AF%E5%88%86%E8%A7%A3/" id="post-next" class="post-nav-link">
        <div class="tips">Next <i class="icon icon-angle-right icon-lg icon-pl"></i></div>
        <h4 class="title">计算机网络——多路复用与多路分解</h4>
      </a>
    </div>
  
</nav>



    




















</article>



</div>

        <footer class="footer">
    <div class="top">
        
<p>
    <span id="busuanzi_container_site_uv" style='display:none'>
        站点总访客数：<span id="busuanzi_value_site_uv"></span>
    </span>
    <span id="busuanzi_container_site_pv" style='display:none'>
        站点总访问量：<span id="busuanzi_value_site_pv"></span>
    </span>
</p>


        <p>
            
                <span><a href="/blog/atom.xml" target="_blank" class="rss" title="rss"><i class="icon icon-lg icon-rss"></i></a></span>
            
            <span>博客内容遵循 <a rel="license noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank">知识共享 署名 - 非商业性 - 相同方式共享 4.0 国际协议</a></span>
        </p>
    </div>
    <div class="bottom">
        <p><span>特务依昂 &copy; 2015 - 2020</span>
            <span>
                
                Power by <a href="http://hexo.io/" target="_blank">Hexo</a> Theme <a href="https://github.com/yscoder/hexo-theme-indigo" target="_blank">indigo</a>
            </span>
        </p>
    </div>
</footer>

    </main>
    <div class="mask" id="mask"></div>
<a href="javascript:;" id="gotop" class="waves-effect waves-circle waves-light"><span class="icon icon-lg icon-chevron-up"></span></a>



<div class="global-share" id="globalShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&title=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&pic=http://tewuyiang.gitee.io/blog/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&title=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&source=一个未来程序员的博客~~~" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《计算机网络——TCP的三次握手与四次挥手》 — 博客主页&url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/&via=http://tewuyiang.gitee.io/blog" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://tewuyiang.gitee.io/blog/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E2%80%94%E2%80%94TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>


<div class="page-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <img src="" alt="微信分享二维码">
</div>




    <script src="//cdn.bootcss.com/node-waves/0.7.4/waves.min.js"></script>
<script>
var BLOG = { ROOT: '/blog/', SHARE: true, REWARD: false };


</script>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/main.min.js"></script>


<div class="search-panel" id="search-panel">
    <ul class="search-result" id="search-result"></ul>
</div>
<template id="search-tpl">
<li class="item">
    <a href="{path}" class="waves-block waves-effect">
        <div class="title ellipsis" title="{title}">{title}</div>
        <div class="flex-row flex-middle">
            <div class="tags ellipsis">
                {tags}
            </div>
            <time class="flex-col time">{date}</time>
        </div>
    </a>
</li>
</template>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/search.min.js" async></script>






<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>



<script>
(function() {
    var OriginTitile = document.title, titleTime;
    document.addEventListener('visibilitychange', function() {
        if (document.hidden) {
            document.title = '人呢，怎么不见了！';
            clearTimeout(titleTime);
        } else {
            document.title = '(つェ⊂)咦!欢迎回来!';
            titleTime = setTimeout(function() {
                document.title = OriginTitile;
            },2000);
        }
    });
})();
</script>



</body>
</html>
